#ifndef MSSI_H
#define MSSI_H

#include <libmslog/mslog.h>
//#include <libmstool/mseventPush.h>
/****************************************************************************
 * Macro definitions
 ***************************************************************************/
#define MAX_PROGRAM		60	//1个TS流中，支持最大解析的节目数量
#define MAX_ES			3	//1个节目中，支持最大的ES数量
#define MAX_STREAM		(MAX_PROGRAM*MAX_ES)	//1个TS流中，支持最大的ES数量
#define MAX_SECTION				10
#define MAX_SECTION_LEN 		1021	//TS包中SECTION最大长度
#define LEN_SECTION_HEADER(offset) 		(SI_HEADER_SIZE_SYNTAX1+offset)
#define MAX_DATASECTION_LEN 	(MAX_SECTION_LEN-LEN_SECTION_HEADER(1))	//TS包中SECTION的最大负荷
#define NUM_TS_MAXSECTION		6	//包含最长SECTION的TS个数

#define MAX_SECTION_BUFLEN	(MAX_SECTION_LEN+184)

/*--------PID相关定义-----------*/
//已占用的PID
#define SI_PID_PAT		(0x0000)
#define SI_PID_CAT		(0x0001)
#define SI_PID_TSDT		(0x0002)
#define SI_PID_NIT		(0x0010)
#define SI_PID_SDT		(0x0011)
#define SI_PID_BAT		(0x0011)
#define SI_PID_EIT		(0x0012)
#define SI_PID_TDT		(0x0014)
#define SI_PID_TOT		(0x0014)
#define SI_PID_NULL		(0x1FFF)
//可使用的PID范围
#define SI_PID_MIN		(0x0010)
#define SI_PID_MAX		(0x1FFE)

#define SI_PID_UNVALID		(0xFFFF)

/*--------Table ID相关定义-----------*/
#define SI_TID_PAT				(0x00)
#define SI_TID_CAT				(0x01)
#define SI_TID_PMT				(0x02)
#define SI_TID_NIT_ACT			(0x40)
#define SI_TID_NIT_OTH			(0X41)
#define SI_TID_SDT_ACT			(0x42)
#define SI_TID_SDT_OTH			(0x46)
#define SI_TID_BAT				(0x4A)
#define SI_TID_EIT_PF_ACT		(0x4E)
#define SI_TID_EIT_PF_OTH		(0x4F)
#define SI_TID_EIT_SCHE_ACT		(0x50) /* 0x50 - 0x5f*/
#define SI_TID_EIT_SCHE_OTH		(0x60) /* 0x60 - 0x6f */
#define SI_TID_TDT				(0x70)
#define SI_TID_TOT				(0x73)

/*--------表长度相关定义-----------*/ 
#define SI_SDTLEN_HEADER			11
#define SI_SDTLEN_HEADER_ServiceDesLoop1		  5
#define SI_SDTLEN_HEADER_ServiceDesLoop2		  5
#define SI_PMTLEN_HEADER			12
#define SI_HEADER_SIZE_SYNTAX1 		8
#define SI_CRCLEN					4
#define SI_HEADER_SIZE      	    3

/*--------TS包相关定义-----------*/
//同步字节
#define TS_SYNC			0x47
#define TS_NULL			0xFF
//TS包长度
#define TS_SIZE_MAX 	204
#define TS_SIZE_FEC 	204
#define TS_SIZE_DVHS 	192
#define TS_SIZE_BASE 	188
//TS包中PES长度
#define TS_SIZE_HEADER 	4
#define TS_SIZE_PES 		184
//TS包长为204时，只是在188的基础上在尾部增加了16个字节的校验数据
#define TS_SIZE_CHECK 	16


/*--------TS包发送和构建相关默认数据-----------*/
#define TS_PACKET_BESTLEN_CUS(pktSize)			(7*pktSize)
#define TS_PACKET_BESTLEN						TS_PACKET_BESTLEN_CUS(TS_SIZE_BASE)
#define TS_DEFAULT_PMTPID 						0x0142
#define TS_DEFAULT_SERVICEID 					0X0001
#define TS_DEFAULT_TRANSPORT_STREAM_ID			0X0001
#define TS_DEFAULT_ORIGINAL_NETWORK_ID 			0XFF01

/*****************************************************
*	Ts头定义
******************************************************/
/*Byte[0]: 同步字节*/
#define TS_GET_SYNC(buf) 						(buf[0])

/*Byte[1:2]: 
	bit[0:12]:PID
	bit[13]:transport priority
	bit[14]:payload unit start indicator
	bit[15]:transport error indicator
*/
#define TS_GET_PID(buf) 						(((((buf)[1]&0x1f)<<8)|(((buf)[2]&0xff)))&0xffff)
#define TS_GET_TRAN_PRIORITY(buf) 				((buf[1]&0x20)>>5)
#define TS_GET_PAYLOAD_UNIT_START_IND(buf)		((buf[1]&0x40)>>6)
#define TS_GET_TRAN_ERR_IND(buf) 				((buf[1]&0x80)>>7)
	
/*Byte[3]: 
	bit[0:3]:continuity counter,0~15
	bit[4:5]:adaption field control
	bit[6:7]:transport scrambling control
*/
#define TS_GET_CC(buf) 								(buf[3]&0x0f)	
#define TS_GET_ADAPTION_FIELD_CONTROL(buf) 			((buf[3]&0x30)>>4)	
#define TS_GET_TRAN_SCRAMBLING_CONTROL(buf) 		((buf[3]&0xc0)>>6)	
/*****************************************************
* :System clock
*****************************************************/
#define TS_TIME_HZ(num)			(num)		
#define TS_TIME_MHZ(num)		(TS_TIME_HZ(num)*1000*1000)		
#define TS_TIMEBASE_SYSTEM		TS_TIME_MHZ(1)		// 1Mhz		us
#define TS_TIMEBASE_DEV			TS_TIME_MHZ(27)		// 27Mhz
#define TS_TIMEEXA_DEV			TS_TIME_HZ(90000)	// 90000 Hz

enum PMT_STREAMType{
	streamtype_res				=0x00,
	streamtype_video_mpeg1		=0x01,	//"11172-2 video (MPEG-1)"		
	streamtype_video_mpeg2		=0x02,	//"13818-2 video (MPEG-2)"
	streamtype_audio_mpeg1		=0x03,	//"11172-3 audio (MPEG-1)"
	streamtype_audio_mpeg2		=0x04,	//"13818-3 audio (MPEG-2)"
	streamtype_private_sections	=0x05,	//"13818-1 private sections"
	streamtype_pes_private_data	=0x06,	//"13818-1 PES private data"
	streamtype_ns_mheg				=0x07,	//"13522 MHEG";
	streamtype_ns_AnnexA_DSM_CC		=0x08,	//"H.222.0/13818-1 Annex A - DSM CC";
	streamtype_ns_h2221				=0x09,	//"H.222.1";
	streamtype_ns_typeA				=0x0A,	//"13818-6 type A";
	streamtype_ns_typeB				=0x0B,	//"13818-6 type B";
	streamtype_ns_typeC				=0x0C,	//"13818-6 type C";
	streamtype_ns_typeD				=0x0D,	//"13818-6 type D";
	streamtype_ns_auxiliary			=0x0E,	//"H.222.0/13818-1 auxiliary";
	streamtype_audio_aac			=0x0F,	//"13818-7 Audio with ADTS transport syntax"
	streamtype_video_mpeg4			=0x10,	//"14496-2 Visual (MPEG-4 part 2 video)"
	streamtype_audio_aac_latm		=0x11,	//"14496-3 Audio with LATM transport syntax (14496-3/AMD 1)"
	streamtype_ns_FlexMux_pes		=0x12,	//"14496-1 SL-packetized or FlexMux stream in PES packets";
	streamtype_ns_FlexMux_14496sec	=0x13,	//"14496-1 SL-packetized or FlexMux stream in 14496 sections";
	streamtype_ns_sync_download		=0x14,	//"ISO/IEC 13818-6 Synchronized Download Protocol";
	streamtype_metadata				=0x15,	//"Metadata in PES packets"
	streamtype_ns_metadata_sections	=0x16,	//"Metadata in metadata_sections";
	streamtype_ns_metadata_138186DataCarousel	=0x17,	//"Metadata in 13818-6 Data Carousel";
	streamtype_ns_metadata_138186ObjectCarousel=0x18,	//"Metadata in 13818-6 Object Carousel";
	streamtype_ns_metadata_138186sync_download	=0x19,	//"Metadata in 13818-6 Synchronized Download Protocol";
	streamtype_ns_mpeg2_ipmp	=0x1A,	//"13818-11 MPEG-2 IPMP stream";
	streamtype_video_h264		=0x1B,	//"H.264/14496-10 video (MPEG-4/AVC)";
	streamtype_video_hevc		=0x24,	//"H.265 video (MPEG-H/HEVC)";
	streamtype_video_cavs		=0x42,	//"AVS Video";
	streamtype_ns_ipmp			=0x7F,	//"IPMP stream";
	streamtype_audio_ac3		=0x81,	//"ATSC A/52";
	streamtype_audio_dts		=0x82,
	streamtype_audio_truehd		=0x83,
	streamtype_ns_sit			=0x86,	//"SCTE 35 Splice Information Table";
	streamtype_audio_eac3		=0x87,	//"ATSC A/52e"
	streamtype_subtitle_pgs		=0x90,
	streamtype_subtitle_igs		=0x91,
	streamtype_subtitle_text	=0x92,
	streamtype_video_dirac		=0xd1,
	streamtype_video_vc1		=0xea,	
	streamtype_max,
};
typedef enum ENUMAVType{
	avtype_unknow=0x00,
	avtype_video,
	avtype_audio,
	avtype_data,         
	avtype_subtitle,
	avtype_attachment,
	avtype_nb,
	avtype_max
}ENUMAVType;

enum {
	servicetype_digital_tv			= 0x01,
	servicetype_digital_radio		= 0x02,
	servicetype_digital_teletext	= 0x03,
	servicetype_advanced_codec_digital_radio	= 0x0A,
	servicetype_mpeg2_digital_hdtv				= 0x11,
	servicetype_advanced_codec_digital_sdtv		= 0x16,
	servicetype_advanced_codec_digital_hdtv		= 0x19,
	servicetype_max								= 0x1a,
};

typedef struct CTUCOUNTERInfo{
//last_cc,expected_cc可以判断是否启用了CC检测	
    ms_bool flag_enable;
	ms_s08 last_cc;
	ms_s08 last_cc_pcr;
	ms_u32 numErr;
}CTUCOUNTERInfo;	

typedef struct TSHEADInfo{
	ms_u08 sync_byte;
	ms_u08 transporterror_indicator;
	ms_u08 payload_unit_start_ind;
	ms_u08 transport_priority;
	ms_u16 pid;
	ms_u08 transport_scrambling_control;
	ms_u08 adaptation_field_ctr;
	ms_u08 continuity_counter;
}TSHEADInfo;

typedef struct SECTIONData{
	ms_bool flag_recvOk;
	ms_u08 adaptation_field_len;
	ms_u16 len_section;
	ms_u08 vrsion_num;
	ms_u08 current_next_indicator;
	ms_u08 section_num;
	ms_u08 section_lastsec;

	ms_s32 table_offset;
	ms_byte data[MAX_SECTION_BUFLEN];
	ms_u16 len_recv;
}SECTIONData;

typedef struct SECTIONContext{
	ms_u16 ts_id;
	ms_u08 vrsion_num;
	SECTIONData sec_data[MAX_SECTION];
	ms_byte data[MAX_SECTION*MAX_SECTION_BUFLEN];
	ms_u16 total_num;
	ms_u08 section_index;
	ms_u16 len_recv;
/*某些分段调整字段太长，导致无法解析有效数据，需要将2个PES进行组合*/	
	ms_bool flag_recombine;
	ms_byte dataRecombine[2*TS_SIZE_PES];
	ms_u08 adaptation_field_len;
}SECTIONContext;

typedef struct PATTABLEInfo{
	ms_byte tag[256];
	ms_u16 transport_stream_id;
	ms_u16 totalnum_program_real;
	ms_u16 totalnum_program;
	ms_u16 pid_nit;
	ms_u16 pid_pmt[MAX_PROGRAM];
	SECTIONContext sct_ctt;
}PATTABLEInfo;

typedef struct SDTInfo{
	ms_u16 serviceid;
	ms_u16 service_type;
	ms_u08 service_name[256];
	ms_u08 service_provider_name[256];
}SDTInfo;

typedef struct SDTTABLEInfo{
	ms_byte tag[256];
	ms_u16 service_id;	
	ms_u16 transport_streamid;
	ms_u16 original_network_id;	
	ms_u16 sdt_num;	
	SDTInfo sdt_info[MAX_PROGRAM];
	SECTIONContext sct_ctt;
}SDTTABLEInfo;

typedef struct MPEGTSPeriod{
	ms_u64 sys_pre;
	ms_u64 sys_cur;
	ms_u64 period;
}MPEGTSPeriod;	

typedef struct MSTIMEBASEInfo{
	int  num;		// 1
	int  den;		// 90000
}MSTIMEBASEInfo;

typedef struct MSAVCODECInfo{
//音频		
	int64_t bit_rate;
	int sample_rate;
	ms_byte channel_layout_string[128];
	ms_byte sample_fmt_string[16];
//视频		
	int width;
	int height;
	float float_fps;
	ms_byte resolution[16];
	ms_byte pix_fmt_string[64];
	ms_byte profile_string[64];
	ms_byte colorspace_string[64];
}MSAVCODECInfo;

typedef struct ESInfo{
	ms_byte tag[256];
	ms_u16 index_pmt; 
	ms_u08 index_es; 
	ms_s32 stream_index;		//流索引
	ms_s32 stream_type_index;	//所属类型的流索引，用于MAP功能
	ms_u16 pid;
	ms_u08 streamType;
	ms_u16 len_esInfo;
	ms_byte esInfo[1024];
//exter	
	ENUMAVType avType;	//0-video
	ms_byte strStreamType[64];
	MSAVCODECInfo  codecInfo;
	MPEGTSPeriod period;	
	CTUCOUNTERInfo	ctuInfo;
//在音视频数据中有PCR数据，但它的PID又不在PMT表中
	ms_u32 numPcr_noInPmt;

//PES
	ms_u64 pts;
	ms_u64 pts_pre;
	ms_u64 dts;
	ms_u64 dts_pre;	
	ms_bool flag_pts;
	ms_bool flag_dts;
	ms_u16 pes_data_len;
	ms_u16 pes_data_recvd;
	ms_u32 numNonmomo[2];	//PTS或DTS非线性
}ESInfo;

typedef struct PMTTABLEInfo{
//PMT表信息
	ms_u16 pid_pcr;
	ms_bool sharePid;
	//ES信息
	ms_s08 num_es; 
	ESInfo esInfo[MAX_ES];
}PMTTABLEInfo;

static inline ms_void mssi_api_headerPrint(TSHEADInfo * ms_in ptshead_info,ms_byte ms_in dugmode)
{
	if(1==dugmode){
		ms_ldebug("mssi","Sync byte:%#x",ptshead_info->sync_byte);
		if (1==ptshead_info->transporterror_indicator){
			ms_lwaring("mssi","transport error indicator:%#x",ptshead_info->transporterror_indicator);
		}else{
			ms_ldebug("mssi","transport error indicator:%#x",ptshead_info->transporterror_indicator);
		}	
		ms_ldebug("mssi","payload unit start indicator:%#x", ptshead_info->payload_unit_start_ind);
		ms_ldebug("mssi","transport priority:%#x",ptshead_info->transport_priority);
		ms_ldebug("mssi","PID:%#x",ptshead_info->pid);
		if (0x00!=ptshead_info->transport_scrambling_control){
			ms_lwaring("mssi","transport scrambling control:%#x",ptshead_info->transport_scrambling_control);
		}else{
			ms_ldebug("mssi","transport scrambling control:%#x",ptshead_info->transport_scrambling_control);
		}	
		ms_ldebug("mssi","transport scrambling control:%#x",ptshead_info->transport_scrambling_control);
		ms_ldebug("mssi","adaption field control:%#x",ptshead_info->adaptation_field_ctr);// DBG_PCR
		ms_ldebug("mssi","continuity counter:%#x",ptshead_info->continuity_counter);	
		ms_ldebug("mssi","");
	}else if(2==dugmode){
		ms_ldebug("mssi","PID,continuity counter:%#x,%#x",ptshead_info->pid,ptshead_info->continuity_counter);	
	}
}
static inline ms_s08 mssi_api_headerParse(TSHEADInfo * ms_out ptshead_info,ms_pu08  ms_in ptspkt,ms_u32 len,ms_bool dbg_header)
{
	if(ms_null==ptshead_info
		&&ms_null==ptspkt){
		return -1;
	}
	if (TS_SYNC!=TS_GET_SYNC(ptspkt )	){
		ms_lwaring("mssi","It is not a ts buf,because the syn_byte is %d ,not %d",TS_GET_SYNC(ptspkt ),TS_SYNC);
		return -1;
	}	
	ptshead_info->pid=TS_GET_PID(ptspkt );	
	ptshead_info->sync_byte=TS_GET_SYNC(ptspkt );
	ptshead_info->transporterror_indicator=TS_GET_TRAN_ERR_IND(ptspkt );
	ptshead_info->payload_unit_start_ind=TS_GET_PAYLOAD_UNIT_START_IND(ptspkt);	
	ptshead_info->transport_priority=TS_GET_TRAN_PRIORITY(ptspkt);	
	ptshead_info->pid=TS_GET_PID(ptspkt );
	ptshead_info->transport_scrambling_control=TS_GET_TRAN_SCRAMBLING_CONTROL(ptspkt );
	ptshead_info->adaptation_field_ctr=TS_GET_ADAPTION_FIELD_CONTROL(ptspkt);
	ptshead_info->continuity_counter=TS_GET_CC(ptspkt );
	mssi_api_headerPrint(ptshead_info,dbg_header);
	return 0;
}

static inline ms_s08 mssi_api_headerBuild(ms_byte*ptspkt,ms_u16 pid,ms_u08 cc,
	ms_byte adaption_field_control,ms_byte payload_unit_start_ind)
{
	ptspkt[0]=TS_SYNC;
/*Byte[1:2]: 
	bit[15]:transport error indicator
	bit[14]:payload unit start indicator
	bit[13]:transport priority
	bit[0:12]:PID
*/
	ptspkt[1]=(0<<7)&0x80;
	ptspkt[1]|=(payload_unit_start_ind<<6)&0x40;
	ptspkt[1]|=(0<<5)&0x20;
	ptspkt[1]|=(pid>>8)&0x1f;
	ptspkt[2]=pid&0xff;
/*Byte[3]: 
	bit[6:7]:transport scrambling control
	bit[4:5]:adaption field control
	bit[0:3]:continuity counter,0~15
*/
	ptspkt[3]=(0<<6)&0xc0;
	ptspkt[3]|=(adaption_field_control<<4)&0x30;
	ptspkt[3]|=cc&0x0f;
}
static inline ms_s08 mssi_api_headerRemap(ms_u16 pid,ms_byte*ptspkt)
{
/*Byte[1:2]: 
	bit[15]:transport error indicator
	bit[14]:payload unit start indicator
	bit[13]:transport priority
	bit[0:12]:PID
*/
	ptspkt[1]&=(~0x1f);
	ptspkt[1]|=(pid>>8)&0x1f;
	ptspkt[2]=pid&0xff;
}
static ms_u08 mssi_api_getSectionNum( ms_u16 data_len)
{
	ms_u08 section_totalNum=(data_len/MAX_DATASECTION_LEN);
	if(data_len%MAX_DATASECTION_LEN){
		section_totalNum+=1;
	}
	return section_totalNum;
}
static ms_u16 mssi_api_getPayloadLen( ms_u16 data_len,ms_u08 index)
{
	if(data_len>MAX_DATASECTION_LEN){
		if((data_len-index*MAX_DATASECTION_LEN)>MAX_DATASECTION_LEN){
			return MAX_DATASECTION_LEN;
		}else{
			return (data_len-index*MAX_DATASECTION_LEN);
		}
	}else{
		return data_len;
	}
}
static ms_void mssi_api_buildSyntax1Head( ms_byte * buf,ms_u08 tid,ms_u16 section_len,ms_u16 ts_id,
	ms_u08 version_num,ms_u08 sectionIndex,ms_u08 last_section_num)
{
/*	table id*/
	buf[0]=(tid&0XFF);
/*	[15:15]section synctax indicator：PAT、PMT置1
	[14:14]0
	[13:12]res
	[11:0]section_len：前2位置为00，因此最大不超过1021*/
	buf[1]=(1<<7)&0x80;
	buf[1]|=(0<<6)&0x40;
	buf[1]|=(3<<4)&0x30;
	buf[1]|=(section_len>>8)&0x0f;
	buf[2]=section_len&0xFF; 
/*	PAT、SDT:transport_stream_id;
	PMT:program_num;
	*/
	ms_network_2b(&buf[3],ts_id);
/*	[7:6]res
	[5:1]version_num：指出PAT的版本号，一旦PAT有变化版本号加1，范围0～31
	[0:0]current_next_indicator*/
	buf[5]=(3<<6)&0xC0;
	buf[5]|=(version_num<<1)&0x3E;
	buf[5]|=(0X01)&0X01;
/*	section_num数目，第一个为0，后面每增加一个分段加1*/
	buf[6]=sectionIndex&0xFF; 
/*	last_section_num：最后一个分段号*/
	buf[7]=last_section_num&0xFF; 
}

static inline ms_s08 mssi_api_tsInit( ms_byte * ptspkt,ms_u16 pid,ms_u08 cc,ms_u08 pktSize,
	ms_byte adaption_field_control,ms_byte payload_unit_start_ind)
{
//初始化数据包
	ms_memset(ptspkt, TS_NULL, TS_SIZE_BASE);
	if(pktSize>TS_SIZE_BASE){
		ms_memset(&ptspkt[TS_SIZE_BASE], 0, (pktSize-TS_SIZE_BASE));
	}

	mssi_api_headerBuild(ptspkt,pid, cc, adaption_field_control,payload_unit_start_ind);
}
	
static inline ms_s08 mssi_api_CCCheck(ms_string destype,CTUCOUNTERInfo *pCtuInfo,unsigned char cur_cc,
	ms_bool flag_av,ms_bool flag_dbg)
{
	ms_s08 ret=0;
	if(ms_true==pCtuInfo->flag_enable){
		ms_s08 expected_cc= (pCtuInfo->last_cc + 1) & 0x0F;
		ms_s08 expected_cc_2= (pCtuInfo->last_cc_pcr + 1) & 0x0F;
		//如果是音视频，PCR的CC可能插入到AV里面，也可能和AV的上一个CC相同；否则不需要考虑PCR；
		ms_bool flag_noCC=(ms_true==flag_av) ? (cur_cc!=expected_cc && cur_cc!=expected_cc_2) : (cur_cc!=expected_cc);
		if(flag_noCC){
			if(cur_cc==pCtuInfo->last_cc){
				if(flag_dbg)ms_lwaring("mssi","%s: Maybe send data again. Last_CC %02d got %02d",destype,
					pCtuInfo->last_cc,cur_cc);
			}else{
				pCtuInfo->numErr++;			
				if(flag_dbg)ms_lwaring("mssi","%s: Continuity check failed! Expected %02d got %02d,errnum:%d",destype,expected_cc,cur_cc,pCtuInfo->numErr);
				ret=-1;
			}
		}else{
			//ms_lverbose("mssi","%s: Expected %02d got %02d",destype,expected_cc,cur_cc);
		}
	}else{
		pCtuInfo->flag_enable=ms_true;
	}
	pCtuInfo->last_cc=cur_cc;
	return ret;
}
	
static inline ms_s08 mssi_api_CCBuild(ms_byte*ptspkt,ms_byte cc)
	
{
/*Byte[3]: 
	bit[6:7]:transport scrambling control
	bit[4:5]:adaption field control
	bit[0:3]:continuity counter,0~15
*/
	ptspkt[3]&=(~0x0F);
	ptspkt[3]|=cc&0x0F;
}

static inline ms_s08 mssi_api_CCBuild2(ms_byte*ptspkt,ms_byte *cc)
{
	mssi_api_CCBuild(ptspkt,(*cc));
	(*cc)+=1;
	if((*cc)>0x0F){
		(*cc)=0x00;
	}
}

static inline ms_u08 mssi_api_getAdaptationFieldLen(ms_u08   adaptation_field_ctr,ms_byte * pes_buf)
{
	ms_u08 adaptation_field_len=0;
	switch(adaptation_field_ctr){
		case 0x0:		//res
			adaptation_field_len=TS_SIZE_PES;
			break;
		case 0x1:		//no adaptation_field_len,payload is 184
			adaptation_field_len=0;
			break;	
		case 0x2:		//no payload,adaptation_field_len must be 183;
			adaptation_field_len=(TS_SIZE_PES-1);
			break;
		case 0x3:		//the adaptation_field_len is rang of(0~182);
			adaptation_field_len=(ms_u08 )(pes_buf[0]&0xFF);
			if(ms_outRange(adaptation_field_len, 0, 182)){
				adaptation_field_len=(TS_SIZE_PES-1);
			}else{
				adaptation_field_len+=1;
			}
			break;
	}
	return adaptation_field_len;
}

static inline ms_byte * mssi_api_setAdaptationFieldLen(ms_u08   adaption_field_control,ms_u16 section_len,
	ms_byte *tsPkt,ms_bool flag_dbg)
{
	ms_u08 adaptation_field_len=0;
	ms_u08 offset=0;
	ms_u08 numTs=(section_len+1+SI_CRCLEN)/TS_SIZE_PES;
	if((section_len+1+SI_CRCLEN)%TS_SIZE_PES){
		numTs+=1;
	}	
	switch(adaption_field_control){
		case 0x0:		//保留
			return ms_null;
		case 0x1:		//没有调整长度，负载长度为184
			return &tsPkt[TS_SIZE_HEADER];
		case 0x2:		//没有负载，调整长度必须是183;
			tsPkt[TS_SIZE_HEADER]=0x00;
			return ms_null;
		case 0x3:		//调整长度范围(0~182);
			adaptation_field_len=numTs*TS_SIZE_PES-1-section_len-SI_CRCLEN;
			offset=adaptation_field_len+1+TS_SIZE_HEADER; 
			tsPkt[TS_SIZE_HEADER]=adaptation_field_len;
			tsPkt[TS_SIZE_HEADER+1]=0x00;
			if(flag_dbg)ms_linfo("SI","section_len:%u(调整字段：%d,偏移：%d, 包个数：%d)",
				section_len,adaptation_field_len,offset,numTs);
			return &tsPkt[offset];
	}
	return ms_null;
}
static inline ms_bool  mssi_api_isValidPid(ms_u16 pid)
{
	if(ms_range(pid, SI_PID_MIN, SI_PID_MAX)){
		return ms_true;
	}else{
		return ms_false;
	}
}
static inline ms_bool  mssi_api_isFFmpegValidPid(ms_u16 pid)
{
	if(SI_PID_SDT==pid){
		ms_lwaring("mssi","FFMPEG will send sdt,so %#x res for sdt",SI_PID_SDT);
	}
	//由于FFMPEG打MPEGTS包，默认有SDT表。如果PID设置和SDT表的PID一致，会存在卡顿问题
	if((ms_true==mssi_api_isValidPid( pid))&&(SI_PID_SDT!=pid)){
		return ms_true;
	}else{
		return ms_false;
	}
}
static inline ms_bool  mssi_api_isValidProgramNum(ms_u16 program_num)
{
/*	0X0000：NIT表用
	0XFFFF：理论保留，实际极少使用*/
	if(ms_range(program_num, 0X0001, 0XFFFE)){
		return ms_true;
	}else{
		return ms_false;
	}
}

static inline ms_bool mssi_api_isPcrData(TSHEADInfo tsHeadInfo,ms_byte *pes_buf)
{	
	if(tsHeadInfo.adaptation_field_ctr==0x3 ||tsHeadInfo.adaptation_field_ctr==0x2){
		ms_u08 adaptation_field_len=(ms_u08 )pes_buf[0];
		//PCR数据至少需要7个字节，调整字段最长为183字节
		if( adaptation_field_len<7 ||adaptation_field_len>183){
			//ms_lerror("mssi" , "[Pid%#x]adaptation_field_len:%d",tsHeadInfo.pid,adaptation_field_len);
			return ms_false;
		}			
		/*当adaptation_field_ctr为0x2时,调整字段长度为183;当adaptation_field_ctr为0x3时,调整字段长度为(0~182);*/
		if(tsHeadInfo.adaptation_field_ctr==0x2 && 183!=adaptation_field_len){
			ms_lerror("mssi" , "[Pid%#x]What shift do you send, when the adaptation_field_ctr is %#x,but the adaptation_field_len isnot 183(%d)",
				tsHeadInfo.pid,tsHeadInfo.adaptation_field_ctr,adaptation_field_len);
			return ms_false;
		}
		ms_byte *adapt_field=&pes_buf[1];
		//获取PCR标记位
		ms_u08 pcr_flag=(adapt_field[0]&0x10)>>4;
		return (pcr_flag) ? ms_true: ms_false;
	}	
	return ms_false;
}

static inline ms_s64 mssi_api_getPcr(char *adapt_field)
{
/*pcr_base以系统时钟频率的1/300为单位的时间值（90khz）*/
	ms_s64 pcr_base=( ((((ms_s64)((adapt_field)[1]))&0xff)<<25) \
					|((((ms_s64)((adapt_field)[2]))&0xff)<<17) \
					|((((ms_s64)((adapt_field)[3]))&0xff)<<9) \
					|((((ms_s64)((adapt_field)[4]))&0xff)<<1) \
					|((((ms_s64)((adapt_field)[5]))&0x80)>>7));
			/*reserved(6bit):((adapt_field[5]) &0x7E )>>1*/
					
/*pcr_ext以系统时钟频率为单位的时间值（27Mhz）*/
	ms_u32 pcr_ext=(((adapt_field)[5])&0x7f) |(((adapt_field)[6])&0x80);

/*返回系统时钟频率为单位的时间值（27Mhz）*/					
	ms_s64 pcr_27Mhz= (ms_s64)pcr_base*300+pcr_ext;
/*转换为系统时间（微妙）*/		
	ms_s64 pcr= pcr_27Mhz/27;
	return pcr;
}
static inline ms_void mssi_api_setPcr(char *adapt_field,ms_s64 pcrval)
{
	ms_s32 pclk_rebase_exa_delay=pcrval%(27000/90);
	ms_s64 pclk_rebase_delay=(ms_s64)(pcrval-pclk_rebase_exa_delay)/(27000/90);
			
	adapt_field[1]=(pclk_rebase_delay>>25)&0xff;
	adapt_field[2]=(pclk_rebase_delay>>17)&0xff;
	adapt_field[3]=(pclk_rebase_delay>>9)&0xff;
	adapt_field[4]=(pclk_rebase_delay>>1)&0xff;
	adapt_field[5]=(((pclk_rebase_delay&0x01)<<7)|(pclk_rebase_exa_delay&0x7f))&0xff;
	adapt_field[6]=(pclk_rebase_exa_delay&0x80);
//check			
	ms_s64 pclk_rebase1=(     ((((ms_s64)((adapt_field)[1]))&0xff)<<25) \
		|((((ms_s64)((adapt_field)[2]))&0xff)<<17) \
		|((((ms_s64)((adapt_field)[3]))&0xff)<<9) \
		|((((ms_s64)((adapt_field)[4]))&0xff)<<1) \
		|((((ms_s64)((adapt_field)[5]))&0x80)>>7)	);
	unsigned int pclk_rebase_exa1=(((adapt_field)[5])&0x7f) |(((adapt_field)[6])&0x80);
	ms_s64 pcr_check=(ms_s64)pclk_rebase1*(27000/90)+pclk_rebase_exa1;
	//ms_debug("pcrval,pcr_check:--------%s,%s", ms_num2str(pcrval), ms_num2str(pcr_check));
}

/*原理:当连续的TS_PACKET_SIZE间隔都是MPEGTS的同步字节，则认为是MPEGTS头*/
static inline ms_bool mssi_api_isTs_byPktSize(ms_byte *buf, ms_s32 len,ms_u32 pktSize)
{
	if(len<(2*pktSize)){
		//ms_lwaring("mssi","The data length (%d) is smaller than the basic length (%d), which may cause errors in the judgment", len,(2*pktSize));
	}
	ms_u32 index=0;
	while( len> (index*pktSize)){
		if(TS_SYNC!=TS_GET_SYNC((&buf[index*pktSize]))){
			return ms_false;
		}
		index++;
	}
	return ms_true;
}

static inline ms_bool mssi_api_isTs(ms_byte *buf, ms_s32 len)
{
	if(mssi_api_isTs_byPktSize(buf, len, TS_SIZE_BASE)
		||mssi_api_isTs_byPktSize(buf, len, TS_SIZE_DVHS)
		||mssi_api_isTs_byPktSize(buf, len, TS_SIZE_FEC)){
		return ms_true;
	}
	return ms_false;
}

/*通过调整字段判断TS*/
static inline ms_bool mssi_api_isTs_byAdaptation(TSHEADInfo tsHeadInfo,ms_byte *tspkt,ms_bool flag_dbg,ms_string tag)
{	
	if(0x1==tsHeadInfo.adaptation_field_ctr||(0==tsHeadInfo.adaptation_field_ctr)){
		return ms_true;
	}else if(tsHeadInfo.adaptation_field_ctr==0x3 ||tsHeadInfo.adaptation_field_ctr==0x2){
		char *pes_buf=&tspkt[TS_SIZE_HEADER];
		ms_u08 adaptation_field_len=(ms_u08 )pes_buf[0];
		//调整字段最长为183字节
		if( adaptation_field_len>183){
			if(flag_dbg)ms_lerror("mssi" , "[%s-Pid%#x]The adaptation_field_ctr is %#x,but the adaptation_field_len:%d",tag,
				tsHeadInfo.pid,tsHeadInfo.adaptation_field_ctr,adaptation_field_len);
			return ms_false;
		}			
		/*当adaptation_field_ctr为0x2时,调整字段长度为183;当adaptation_field_ctr为0x3时,调整字段长度为(0~182);*/
		if(tsHeadInfo.adaptation_field_ctr==0x2 && 183!=adaptation_field_len){
			if(flag_dbg)ms_lerror("mssi" , "[%s-Pid%#x]The adaptation_field_ctr is %#x,but the adaptation_field_len isnot 183(%d)",tag,
				tsHeadInfo.pid,tsHeadInfo.adaptation_field_ctr,adaptation_field_len);
			return ms_false;
		}
		return ms_true;
	}	
	return ms_false;
}
/*获取TS的包大小*/
static inline ms_u08 mssi_api_getPktSize(ms_byte *buf, ms_s32 len)
{
	if(mssi_api_isTs_byPktSize(buf, len, TS_SIZE_BASE)){
		return TS_SIZE_BASE;
	}else if(mssi_api_isTs_byPktSize(buf, len, TS_SIZE_DVHS)){
		return TS_SIZE_DVHS;
	}else if(mssi_api_isTs_byPktSize(buf, len, TS_SIZE_FEC)){
		return TS_SIZE_FEC;
	}else{
		return TS_SIZE_BASE;
	}
}

/*获取TS第一个同步字节的偏移量*/
static inline ms_s32 mssi_api_getTsOffset(ms_byte *buf, ms_s32 len)
{
	for(ms_s32 index=0;index<len;index++){
		if(ms_true==mssi_api_isTs(&buf[index], (len-index))){
			return index;
		}
	}
	return len;
}

#endif

